package Objects
{
	import Config.GameConfig;
	
	import Controls.DragProxy;
	import Controls.ToolTip;
	
	import Input.GameInput;
	
	import Native.INativeObject;
	
	import Scenes.GameScene;
	
	import Setup.ZOrder;
	
	import Tools.DisplayTool;
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.filters.BitmapFilter;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.Rectangle;
	import flash.utils.getQualifiedClassName;
	
    public class GameObject
	{
		protected var ticks:int = 0;
		public var toSyncRemoved:Boolean=false;
		public var selected:Boolean=false;
		private var grayed:Boolean=false;
		public var intelligent:Boolean=false;
        public var name:String;
        public var parent:GameObject;
        public var obj:DisplayObject;
        public var children:Array;
		public var gs:GameScene;
		public var removed:Boolean=false;
		public var pixelCheck:Boolean=false;
		private var tintColor:int=-1;
		public var checkMouse:Boolean=true;
		public var toolTipData:Object;
		public var toolTipClass:Class;
		public var toolTip:ToolTip;
		public var buttonCursor:Boolean=false;
		public var activeOver:Boolean=false;
		private var doActiveOvered:Boolean=false;
		public var overed:Boolean=false;
		public var canDrag:Boolean=false;
		public var dragProxy:DragProxy;
		public var dragProxyClass:Class;
		public var statistical:Boolean=false;
		
        public function GameObject(objData:Object):void
		{
            super();
			if (objData is DisplayObject)
			{
				obj = DisplayObject(objData);
			}
			if (objData is Class)
			{
				obj = new objData();
			}
			if(obj is INativeObject)
			{
				INativeObject(obj).go=this;
			}
			toolTipClass=GameConfig.toolTipClass;
			dragProxyClass=GameConfig.dragProxyClass;
			children = new Array();
			gs=GameScene.gs;
			gs.objects.push(this);
        }
		public function update():void
		{
			if(pauseUpdate)return;
			ticks++;
			$update();
			_update();
		}
		protected function $update():void
		{
			
		}
		protected function _update():void
		{
			
		}
		protected function get pauseUpdate():Boolean
		{
			return false;
		}
		public function syncRemoved():void
		{
			children = children.filter(function (go:GameObject, index:int, arr:Array):Boolean{
				return !go.removed;
			});
		}
        public function bringToFront():void
		{
            DisplayTool.bringToFront(obj);
        }
		public function bringToBack():void
		{
			DisplayTool.bringToBack(obj);
		}
		public function get mDown():Boolean
		{
			return GameInput.i.mDown&&mOver;
		}
        public function get mHit():Boolean
		{
			if(gs.mHit)
			{
				if(mOver)
				{
					return true;
				}
			}
			return false;
        }
		public function get mOver():Boolean
		{
			if(gs.draging)
			{
				return false;
			}
			return overed;
		}
		public function addChild(child:GameObject):void
		{
			child.parent=this;
			if(child.intelligent)
			{
				child.update();
			}
			children.push(child);
			var container:DisplayObjectContainer=obj as DisplayObjectContainer;
			container.addChild(child.obj);
		}
		public function tint(color:uint,strength:Number=1):void
		{
			if(tintColor==color)return;
			
			tintColor=color;
			
			DisplayTool.tint(obj,color,strength);
			
		}
		public function get globalBounds():Rectangle
		{
			return obj.getBounds(gs.m);
		}
		public function collidesWith(go:GameObject):Boolean
		{
			return collidesBounds.intersects(go.collidesBounds);
		}
		public function get collidesBounds():Rectangle
		{
			return obj.getBounds(gs.m);
		}
		public function moveTo(x:Number,y:Number,handleX:Number=0,handleY:Number=0):void
		{
			DisplayTool.moveTo(obj,x,y,handleX,handleY);
		}
		public function gray():void
		{
			if(grayed)return;
			
			var matrix:Array = new Array();
			matrix = matrix.concat([0.3086, 0.6094, 0.0820, 0, 0]);
			matrix = matrix.concat([0.3086, 0.6094, 0.0820, 0, 0]);
			matrix = matrix.concat([0.3086, 0.6094, 0.0820, 0, 0]);
			matrix = matrix.concat([0, 0, 0, 1, 0]);
			var filter:BitmapFilter=new ColorMatrixFilter(matrix);
			addFilter(filter);
			
			grayed=true;
		}
		public function degray():void
		{
			if(!grayed)return;
			
			removeFilter(ColorMatrixFilter);
			
			grayed=false;
		}
		public function addFilter(filter:BitmapFilter):void
		{
			var filters:Array=obj.filters;
			
			var index:int=filters.length-1;
			while(index>=0)
			{
				var temp:BitmapFilter=filters[index];
				var className1:String=getQualifiedClassName(temp);
				var className2:String=getQualifiedClassName(filter);
				if(className1==className2)
				{
					filters.splice(index,1);
				}
				index--;
			}
			
			filters.push(filter);
			obj.filters=filters;
			
		}
		public function get originalWidth():Number
		{
			return obj.width/obj.scaleX;
		}
		public function get originalHeight():Number
		{
			return obj.height/obj.scaleY;
		}
		public function removeFilter(filterClass:Class):void
		{
			var filters:Array=obj.filters;
			
			var index:int=filters.length-1;
			while(index>=0)
			{
				var temp:BitmapFilter=filters[index];
				if(temp is filterClass )
				{
					filters.splice(index,1);
				}
				index--;
			}
			
			obj.filters=filters;
		}
		public function createToolTip():void
		{
			if(!toolTip)
			{
				toolTip=new toolTipClass();
				toolTip.go=this;
				toolTip.setup(toolTipData);
				gs.addGameObject(toolTip,ZOrder.TIPS);
			}
		}
		public function createDragProxy():void
		{
			if(!dragProxy)
			{
				dragProxy=new dragProxyClass();
				dragProxy.go=this;
				dragProxy.setup();
				gs.addGameObject(dragProxy,ZOrder.TIPS);
			}
		}
		public final function doActiveOver():void
		{
			if(doActiveOvered)return;
			_doActiveOver();
			doActiveOvered=true;
		}
		public final function unActiveOver():void
		{
			if(!doActiveOvered)return;
			_unActiveOver();
			doActiveOvered=false;
		}
		protected function _doActiveOver():void
		{
			tint(0x646464);
		}
		protected function _unActiveOver():void
		{
			tint(0x000000);
		}
		public function verifyDrag(go:GameObject):Boolean
		{
			return false;
		}
		public function acceptDrag(go:GameObject):void
		{
			
		}
		public function onScreenResize():void
		{
			
		}
		public final function remove():void
		{
			if(obj.parent)
			{
				obj.parent.removeChild(obj);
			}
			for each(var child:GameObject in children)
			{
				child.remove();
			}
			if(parent)
			{
				parent.toSyncRemoved=true;
			}
			gs.toSyncRemoved=true;
			$remove();
			_remove();
			removed=true;
		}
		protected function $remove():void
		{
			
		}
		protected function _remove():void
		{
			
		}
    }
}